package com.ztesoft.web.taskscheduling.service.impl;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ztesoft.framework.exception.BaseAppException;
import com.ztesoft.framework.log.ZTEsoftLogManager;
import com.ztesoft.framework.util.DateUtils;
import com.ztesoft.framework.util.Utils;
import com.ztesoft.web.backup.service.BackUpService;
import com.ztesoft.web.checkup.service.CheckUpService;
import com.ztesoft.web.cleanup.service.CleanUpService;
import com.ztesoft.web.common.DMSConstant;
import com.ztesoft.web.common.customdb.dao.DmTaskStageCustomDao;
import com.ztesoft.web.common.customdb.dao.DmTaskStageDefineCustomDao;
import com.ztesoft.web.common.db.dao.SysParamDao;
import com.ztesoft.web.taskgenerator.db.arg.DmTaskArg;
import com.ztesoft.web.taskgenerator.db.dao.DmTaskDao;
import com.ztesoft.web.taskgenerator.db.dao.DmTaskStageDao;
import com.ztesoft.web.taskgenerator.db.po.DmTaskPO;
import com.ztesoft.web.taskgenerator.db.po.DmTaskStageDefinePO;
import com.ztesoft.web.taskgenerator.db.po.DmTaskStagePO;
import com.ztesoft.web.taskscheduling.service.TaskExecchildThreadService;

/**
 * 调度处理
 */
@Service("TaskExecchildThreadServiceImpl")
public class TaskExecchildThreadServiceImpl implements TaskExecchildThreadService {
	
	private static final ZTEsoftLogManager LOGGER = ZTEsoftLogManager.getLogger(TaskExecchildThreadServiceImpl.class);

	@Autowired
	private DmTaskDao taskDao;
	@Autowired
	private DmTaskStageDao taskStageDao;
	@Autowired
	private DmTaskStageDefineCustomDao taskStageDefineDao;
	@Autowired
	private SysParamDao sysParamDao;
	@Autowired
	private CheckUpService checkUpService;
	@Autowired
	private BackUpService backUpService;
	@Autowired
	private CleanUpService cleanUpService;
	@Autowired
	private DmTaskDao dmTaskDao;
	@Autowired
	private DmTaskStageCustomDao taskStageCustomDao;

	@Override
	public DmTaskPO runningScheduling(List<DmTaskStagePO> stageLst, Integer taskId) {
		Integer stage;
		Integer priority ;
		DmTaskStageDefinePO taskStageDefinePO;
		DmTaskPO dmTaskPO = null;
		String code = null;//异常编码
		
		try {
			for(DmTaskStagePO dmTaskStagePO : stageLst) {
				code = DMSConstant.taskInstList.get(taskId).getStatus();
				LOGGER.info("任务TaskID={1}当前系统状态{0}:",code,taskId);
				//接收01P的状态
				if(DMSConstant.Status.DELAYPAUSE.toString().equals(code)){
					updateDmTaskStateDelay(taskId,"01P", false, true);
					break;
				}else if(DMSConstant.Status.PAUSE.toString().equals(code)){
					break;
				}else if(DMSConstant.Status.CANCEL.toString().equals(code)){
					break;
				}else if(DMSConstant.Status.SYSPAUSE.toString().equals(code)){
					break;
				}else if(selectDmTaskStage(taskId)){
					break;
				}
				List<DmTaskStagePO> stageList = taskStageDao.selectStage(dmTaskStagePO.getDmStrategyId(), taskId);//获取当前环节
				LOGGER.info("获取当前待执行环节:{0}",stageList.size());
				if(Utils.isEmpty(stageList)){
					continue;
				}
				stage = stageList.get(0).getStage();
				priority = 1;
				if(stage==0 && DMSConstant.IS_CHECKUP){
					dmTaskPO = updateDmTaskState(taskId,"00R",true,false);
					LOGGER.info("任务ID={0},策略ID={1}|の调度体检方法开始：",taskId,dmTaskStagePO.getDmStrategyId());
					String checkupResult = checkUpService.notransCheckUp(taskId, dmTaskStagePO.getDmStrategyId());
					LOGGER.info("任务ID={0},策略ID={1}|の调度体检方法执行结束,状态{2}：",taskId,dmTaskStagePO.getDmStrategyId(),checkupResult);
					
					if (!dealResult(checkupResult, taskId)) {//体检不通过
						continue;
					}
					if(dmTaskStagePO.getTaskCheck()==2){
						LOGGER.debug("任务ID={0},策略ID={1}待审核",taskId, dmTaskStagePO.getDmStrategyId());
						dmTaskPO = updateDmTaskState(taskId,"00T", false, false);
					} else if (dmTaskStagePO.getTaskCheck()==0){//若需要人工审核(is_check!=0)，则执行下一个策略，否则进入下一个环节
						taskStageDefinePO = taskStageDefineDao.selectTaskStage(dmTaskStagePO.getOperType(), 0, priority);
						if("F".equals(taskStageDefinePO.getIsLastStage())){
							taskStageDefinePO = taskStageDefineDao.selectTaskStage(dmTaskStagePO.getOperType(), null, priority+1);
							if(taskStageDefinePO.getStage()==1 && DMSConstant.IS_BACKUP){//体检-》备份-》清理
								dmTaskPO = startWithBackUp(dmTaskPO, dmTaskStagePO);
							} else if (DMSConstant.IS_CLEANUP){//体检-》清理
								dmTaskPO = startWithCleanUp(dmTaskPO,dmTaskStagePO);
							}
						}else{//更新下一个策略
							dmTaskPO = updateDmTaskState(taskId,nextTaskState(taskId), false, true);
						}
					}
				}else if (stage==1 && dmTaskStagePO.getTaskCheck()==0 && DMSConstant.IS_BACKUP){//备份
					dmTaskPO = updateDmTaskState(taskId,"00R",true,false);
					dmTaskPO = startWithBackUp(dmTaskPO, dmTaskStagePO);
				}else if(stage==2 && dmTaskStagePO.getTaskCheck()==0 && DMSConstant.IS_CLEANUP){//清理
					dmTaskPO = updateDmTaskState(taskId,"00R",true,false);
					dmTaskPO = startWithCleanUp(dmTaskPO,dmTaskStagePO);
				}
			}
		} catch (Exception e) {
			LOGGER.error("taskExecchildThread异常信息|",e);
			dmTaskPO = updateDmTaskState(taskId,"00F", false, true);
		}
		return dmTaskPO;
	}


	private DmTaskPO startWithBackUp(DmTaskPO dmTaskPO, DmTaskStagePO dmTaskStagePO) throws BaseAppException {
		LOGGER.info("任务ID={0},策略ID={1}|の调度备份方法开始：",dmTaskPO.getDmTaskId(),dmTaskStagePO.getDmStrategyId());
		String backupResult = backUpService.backUpProcess(dmTaskPO.getDmTaskId(), dmTaskStagePO.getDmStrategyId());
		LOGGER.info("任务ID={0},策略ID={1}|の调度备份方法执行结束,状态{2}：",dmTaskPO.getDmTaskId(),dmTaskStagePO.getDmStrategyId(),backupResult);
		if(dealResult(backupResult,dmTaskPO.getDmTaskId()) && DMSConstant.IS_BACKUP){//备份成功执行清理
			dmTaskPO = startWithCleanUp(dmTaskPO,dmTaskStagePO);
		}
		return dmTaskPO;
	}


	private DmTaskPO startWithCleanUp(DmTaskPO dmTaskPO,
			DmTaskStagePO dmTaskStagePO) throws BaseAppException {
		LOGGER.info("任务ID={0},策略ID={1}|清理|の调度清理方法开始：",dmTaskPO.getDmTaskId(),dmTaskStagePO.getDmStrategyId());
		String cleanupResult = cleanUpService.cleanUp(dmTaskPO.getDmTaskId(), dmTaskStagePO.getDmStrategyId());
		if(dealResult(cleanupResult, dmTaskPO.getDmTaskId())) {
			dmTaskPO = updateDmTaskState(dmTaskPO.getDmTaskId(),nextTaskState(dmTaskPO.getDmTaskId()), false, true);
		}
		LOGGER.info("任务ID={0},策略ID={1}|清理|の调度清理方法执行结束,状态{2}：",dmTaskPO.getDmTaskId(),dmTaskStagePO.getDmStrategyId(),cleanupResult);
		return dmTaskPO;
	}


	private DmTaskPO updateDmTaskStateDelay(Integer taskId, String state,  Boolean StartDate, Boolean endDate) {
		DmTaskArg art = new DmTaskArg();
		DmTaskPO po = new DmTaskPO();
		DmTaskArg.DmTaskCriteria taskd = art.createCriteria();
		po.setState(state);
		po.setStateDate(new Date());
		taskd.andDmTaskIdEqualTo(taskId);
		dmTaskDao.updateByArgSelective(po, art);
		return po;
	}
	/**
	 * 如果一个策略失败，任务的其他策略停止执行
	 * @param taskId
	 * @return
	 */
	private boolean selectDmTaskStage(Integer taskId){
		boolean flag = false;
		if("00F".equals(dmTaskDao.selectByPrimaryKey(taskId).getState())){
			flag = true;
		}
		return flag;
	}
	/**
	 * 更新任务表状态
	 * @param taskId
	 * @param state
	 * @param StartDate
	 * @param endDate
	 * @return
	 */
	private DmTaskPO updateDmTaskState(Integer taskId, String state,  boolean isBeginDate, boolean isEndDate) {
		DmTaskPO dmTaskPO = new DmTaskPO();
		//接收01P的状态
		String code=  DMSConstant.taskInstList.get(taskId).getStatus();
		if(!DMSConstant.Status.DELAYPAUSE.toString().equals(code)){
			dmTaskPO.setState(state);
		}else{
			dmTaskPO.setState("01P");
		}
		if(DMSConstant.Status.CANCEL.toString().equals(state)){
			dmTaskPO.setNeedSubtask("F");
			dmTaskPO.setIsCheck(0);
		}
		dmTaskPO.setDmTaskId(taskId);
		//任务开始时间
		dmTaskPO.setStartTime(isBeginDate ? new Date() : null);
		//任务结束时间
		dmTaskPO.setEndTime(isEndDate ? new Date() : null);
		taskDao.updateByPrimaryKeySelective(dmTaskPO);
		return dmTaskPO;
	}
	
	@Override
	public Boolean isInBusTime(){
		
		SimpleDateFormat dateFormt =  new SimpleDateFormat(DateUtils.STR_DEFAULT_DATE_FORMAT_WITH_SPLIT);//yyyy-MM-dd HH:mm:ss 
		// 应用启动时获取系统配置相关参数：
		// 1.1营业开始时间,1.2营业结束时间,1.3当前时间
		String busStartTime = sysParamDao.selectByParamName("BUS_START_TIME").getParamValue();
		if("".equals(busStartTime)){
			busStartTime="220000";
		}
		String busEndTime = sysParamDao.selectByParamName("BUS_END_TIME").getParamValue();
		if("".equals(busEndTime)){
			busEndTime="060000";
		}
		String now = dateFormt.format(new Date()).substring(11, 19);//获取时分秒 
		return Utils.isInRange(now, busStartTime, busEndTime);
	}
	
	/**
	 * 有下一个策略，则返回00T,继续执行任务，没有的话直接返回00A,任务完成
	 * @param taskId
	 * @return
	 */
	private String nextTaskState(int taskId){
		String stateStr;
		List<DmTaskStagePO> stageLst = taskStageDao.selectCurrentState(taskId,"00T");
		if(Utils.isEmpty(stageLst)){
			stateStr = "00A";
		}else{
			stateStr = "00T";
		}
		return stateStr;
	}
	/**
	 * 体检、备份、清理结果处理，成功则执行下一个步骤，错误、暂停等则改任务表状态结束任务
	 * @param result
	 * @return
	 */
	private boolean dealResult(String result, int taskId) {
		if ("00A".equals(result)) {
			return true;
		} else if ("00F".equals(result) || "00C".equals(result) || "00P".equals(result) || "02P".equals(result)) {
			updateDmTaskState(taskId, result, false, true);
			return false;
		} else if ("50E".equals(result)) {//体检数据量为空，任务状态为完成
			String nextTaskState = nextTaskState(taskId);
			updateDmTaskState(taskId, nextTaskState, false, true);
			int[] taskIdArr = new int[]{taskId};
			if ("00A".equals(nextTaskState)) {//	
				dmTaskDao.updateTask_(0, taskIdArr);
//				dmTaskStageCustomDao.updateTaskStage_(0, taskIdArr, "审核任务|TASK_ID:|通过||审批理由:待体检数据量为空，更新处理");
			}
			return false;
		} 
		return false;
	}


}
